package com.novunda.platform.web;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.novunda.platform.common.exception.ValidationErrorException;
import com.novunda.platform.common.utils.CheckNameUtil;
import com.novunda.platform.common.utils.StringUtil;
import com.novunda.platform.common.utils.UserUtils;
import com.novunda.platform.common.web.controller.BaseController;
import com.novunda.platform.common.web.modal.Page;
import com.novunda.platform.entities.Menu;
import com.novunda.platform.entities.Office;
import com.novunda.platform.entities.Role;
import com.novunda.platform.entities.User;
import com.novunda.platform.services.OfficeService;
import com.novunda.platform.services.PlatformService;
import com.novunda.platform.services.RoleService;

/**
 * . 功能说明：角色controller
 * 
 * @author linfeng
 * @since 2016/9/5
 * @version 1.0
 * @modify FJ
 */
@Controller
@RequestMapping(value = "/sys/role")
public class RoleController extends BaseController {

	/**
	 * . 角色列表url
	 */
	private String ROLE_URL = "redirect:/sys/role/";

	/**
	 * . 平台service
	 */
	@Autowired
	private PlatformService platformService;

	/**
	 * . 机构service
	 */
	@Autowired
	private OfficeService officeService;

	/**
	 * . 角色service
	 */
	@Autowired
	private RoleService roleService;

	/**
	 * . 功能说明：根据id获取角色，没有则新建一个角色对象
	 * 
	 * @param id
	 *            角色id
	 * @return
	 */
	@ModelAttribute("role")
	public Role get(@RequestParam(required = false) Long id) {
		// 角色id为空
		if (id != null) {
			return roleService.getRole(id);
		} else {
			return new Role();
		}
	}

	/**
	 * . 功能说明：查询角色列表
	 * 
	 * @param role
	 *            角色对象
	 * @param model
	 * @return
	 */
	@RequiresPermissions("sys:role:view")
	@RequestMapping(value = { "list", "" })
	public String list(Role role, HttpServletRequest request, HttpServletResponse response, Model model) {
		Page<Role> page = roleService.findRolePage(new Page<Role>(request, response), role);
		model.addAttribute("page", page);
		return "modules/sys/roleList";
	}

	/**
	 * . 功能说明：添加、修改角色跳转页面
	 * 
	 * @param role
	 *            角色对象
	 * @param model
	 * @return
	 */
	@RequiresPermissions("sys:role:view")
	@RequestMapping(value = "form")
	public String form(Role role, Model model) {
		if(role == null){
			addMessage(model, "当前角色不存在");
			return ROLE_URL;
		}
		User user = UserUtils.getUser();
		// 如果没有指定角色的机构则默认当前登录人所在的机构
		if (role.getOffice() == null) {
			role.setOffice(user.getCompany());
		}
		model.addAttribute("role", role);
		model.addAttribute("menuList", platformService.findAllMenu());
		model.addAttribute("officeList", officeService.findAll());

		return "modules/sys/roleForm";
	}

	/**
	 * . 功能说明：获取机构树结构
	 * 
	 * @param call
	 * @param response
	 * @return
	 */
	@RequiresUser
	@ResponseBody
	@RequestMapping(value = "allOffices", produces = "application/json; charset=UTF-8")
	public List<Map<String, Object>> allOffices(@RequestParam(required = false) String call,
			HttpServletResponse response) {

		List<Map<String, Object>> mapList = Lists.newArrayList();
		List<Office> list = officeService.findAll();
		for (Office e : list) {
			Map<String, Object> map = Maps.newHashMap();
			map.put("id", e.getId());
			map.put("pId", e.getParent() != null ? e.getParent().getId() : 0);
			map.put("name", e.getName());
			mapList.add(map);
		}

		return mapList;

	}

	/**
	 * . 功能说明：获取权限菜单树结构
	 * 
	 * @param call
	 * @param response
	 * @return
	 */
	@RequiresUser
	@ResponseBody
	@RequestMapping(value = "allMenus", produces = "application/json; charset=UTF-8")
	public List<Map<String, Object>> allMenus(@RequestParam(required = false) String call,
			HttpServletResponse response) {

		List<Map<String, Object>> mapList = Lists.newArrayList();
		List<Menu> list = platformService.findAllMenu();
		for (Menu e : list) {
			Map<String, Object> map = Maps.newHashMap();
			map.put("id", e.getId());
			map.put("pId", e.getParent() != null ? e.getParent().getId() : 0);
			map.put("name", e.getName());
			mapList.add(map);
		}

		return mapList;

	}

	/**
	 * . 功能说明：保存角色
	 * 
	 * @param role
	 *            角色实体
	 * @param model
	 * @param redirectAttributes
	 * @return
	 */
	@RequiresPermissions(value = {"sys:role:edit","sys:role:add"},logical=Logical.OR)
	@RequestMapping(value = "save", method = RequestMethod.POST)
	public String save(Role role, Model model, RedirectAttributes redirectAttributes) {
		try {
			// 服务端参数有效性验证
			if (!beanValidator(model, role)) {
				return form(role, model);
			}

			// id为空添加操作，验证角色名
			if (null == role.getId()) {
				String name = role.getName();
				String title = "角色名";
				CheckNameUtil.checkNameIsNull(title, name);
				CheckNameUtil.checkEnChNumTwentyPattern(title, name);
				// String enname = role.getEnname();
				// try {
				// CheckNameUtil.checkNameIsNull("角色英文名", enname);
				// CheckNameUtil.checkRoleEnNamePattern(enname);
				// } catch (ValidationErrorException e) {
				// addMessage(model, "保存角色'" + enname + "'失败, " +
				// e.getMessage());
				// return form(role, model);
				// }
				if (platformService.findRoleByNameAndOffice(name, role.getOffice().getId()) != null) {
					addMessage(model, "保存角色'" + role.getName() + "'失败, 角色名已存在");
					return form(role, model);
				}
			}

			platformService.saveRole(role);
			addMessage(redirectAttributes, "保存角色'" + role.getName() + "'成功");
		} catch (ValidationErrorException e) {
			addMessage(model, "保存角色'" + role.getName() + "'失败, " + e.getMessage());
			return form(role, model);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			addMessage(model, "保存角色失败，异常：" + e.getMessage());
			return form(role, model);
		}
		return ROLE_URL;
	}

	/**
	 * . 功能说明：get保存
	 * 
	 * @param role
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "save", method = RequestMethod.GET)
	public String getSave(Role role, Model model, HttpServletRequest request, HttpServletResponse response) {
		return list(role, request, response, model);
	}

	/**
	 * . 功能说明：删除角色
	 * 
	 * @param id
	 *            角色id
	 * @param redirectAttributes
	 * @return
	 */
	@RequiresPermissions("sys:role:delete")
	@RequestMapping(value = "delete")
	public String delete(@RequestParam Long id, RedirectAttributes redirectAttributes) {
		Role role = roleService.getRole(id);
		if(role == null){
			addMessage(redirectAttributes, "该角色已经删除！");
			return ROLE_URL;
		}

		List<User> userList = role.getUserList();
		// 如果该角色有关联用户
		if (null != userList && !userList.isEmpty()) {
			addMessage(redirectAttributes, "删除角色失败, 该角色有关联的用户，不允许删除");
			return ROLE_URL;
		}
		// 如果该角色是admin
		if (Role.isAdmin(id)) {
			addMessage(redirectAttributes, "删除角色失败, 不允许内置角色或编号空");
			return ROLE_URL;
		}
		// 如果该角色是当前登录人的角色
		if (UserUtils.getUser().getRoleIdList().contains(id)) {
			addMessage(redirectAttributes, "删除角色失败, 不能删除当前用户所在角色");
			return ROLE_URL;
		}
		platformService.deleteRole(id);
		addMessage(redirectAttributes, "删除角色成功");
		return ROLE_URL;
	}

	@RequiresPermissions("sys:role:view")
	@RequestMapping(value = "usertorole")
	public String selectUserToRole(HttpServletRequest request, Role role, Model model) {
		model.addAttribute("role", role);
		model.addAttribute("selectIds", role.getUserIds());
		model.addAttribute("officeList", officeService.findAll());
		model.addAttribute("title", request.getParameter("title"));
		return "modules/sys/selectUserToRole";
	}

	/**
	 * . 功能说明：检查角色名
	 * 
	 * @param name
	 *            角色名
	 * @param officeId
	 *            机构id
	 * @param roleId
	 *            角色id
	 * @return
	 */
	@RequiresUser
	@ResponseBody
	@RequestMapping(value = "checkName")
	@RequiresPermissions("sys:role:view")
	public String checkName(String name, long officeId, String roleId) {
		// 角色id为空
		if (!StringUtil.isEmpty(roleId)) {
			return "true";
		}
		// 角色名字不为空
		if (name != null && platformService.findRoleByNameAndOffice(name, officeId) == null) {
			return "true";
		}
		return "false";
	}

	/**
	 * . 功能说明：新建账号时选择机构，联动机构下的角色
	 * 
	 * @param orgId
	 *            机构id
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "getRoleByOrg", produces = "application/json;charset=utf-8")
	@RequiresPermissions("sys:role:view")
	public List<Role> getRoleByOrg(long orgId) {
		// 该机构下的所有角色
		List<Role> list = roleService.findRoleByOrg(orgId);
		// 当前登录人所拥有角色权限范围内的角色
		List<Role> roleList = platformService.findAllRole();
		List<Long> ids = new ArrayList<Long>();
		for (Role r : roleList) {
			ids.add(r.getId());
		}
		List<Role> roles = new ArrayList<Role>();
		for (Role role : list) {
			// 如果角色权限范围内的角色包含该角色则添加进集合返回页面
			if (ids.contains(role.getId())) {
				Role newRole = new Role();
				newRole.setId(role.getId());
				newRole.setName(role.getName());
				roles.add(newRole);
			}
		}
		return roles;
	}

}
